package com.xd.common.config;

import com.xd.common.filter.H5JwtAuthenticationTokenFilter;
import com.xd.common.filter.JwtAuthenticationTokenFilter;
import com.xd.common.smsLogin.H5MobilecodeAuthenticationProvider;
import com.xd.common.smsLogin.MobilecodeAuthenticationProvider;
import com.xd.core.system.service.H5MyUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled =true) //开启授权注解功能
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private AuthenticationEntryPoint authenticationEntryPoint;
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private H5MyUserDetailsService h5MyUserDetailsService;

    @Autowired
    private AccessDeniedHandler accessDeniedHandler;

    @Autowired
    JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
    @Autowired
    H5JwtAuthenticationTokenFilter h5JwtAuthenticationTokenFilter;


    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                //关闭csrf
                .csrf().disable()
                //不通过Session获取SecurityContext
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                // 对于登录接口 允许匿名访问
                .antMatchers("/user/login").permitAll()
                .antMatchers("/user/smslogin").permitAll()
                .antMatchers("/user/h5Smslogin").permitAll()
                .antMatchers("/user/allopatricLogin").permitAll()
                .antMatchers("/open/apiv1/**").permitAll()
                .antMatchers("/core/dictionary/listByTypeH5").anonymous()
                .antMatchers("/doc.html").anonymous()
                // 除上面外的所有请求全部需要鉴权认证
                .antMatchers(
                        HttpMethod.GET,
                        "/*.html",
                        "/**/*.html",
                        "/**/*.css",
                        "/**/*.jpg",
                        "/**/*.png",
                        "/**/*.woff",
                        "/**/*.js"

                ).permitAll()
                .antMatchers("/profile/**").anonymous()
                .antMatchers("/common/download").permitAll()
                .antMatchers("/common/download/resource").permitAll()
                .antMatchers("/swagger-ui.html").anonymous()
//                .antMatchers("/user/register").anonymous()
                .antMatchers("/swagger-resources/**").anonymous()
                .antMatchers("/webjars/**").anonymous()
                .antMatchers("/*/api-docs").anonymous()
                .antMatchers("/druid/**").anonymous()
                .antMatchers("/api-doc/*").anonymous()
                .antMatchers("/msm/send/**").anonymous()
                .antMatchers("/notify/**").permitAll()
                .antMatchers("/core/h5/**").permitAll()
                .anyRequest().authenticated();
//                .and()
//                .sessionManagement()
//                //session失效的时候，跳转的地址
//                .invalidSessionUrl("/user/login")
//                .maximumSessions(1)
//                .expiredSessionStrategy(sessionInformationExpiredStrategy);
        http.exceptionHandling()
                //认证失败处理器
                .authenticationEntryPoint(authenticationEntryPoint)
                .accessDeniedHandler(accessDeniedHandler);
        //把token校验过滤器添加到过滤器链中
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        http.addFilterBefore(h5JwtAuthenticationTokenFilter, JwtAuthenticationTokenFilter.class);
        http.cors();//允许跨域
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        List authenticationProviders = new ArrayList();
        authenticationProviders.add(mobilecodeAuthenticationProvider());
        authenticationProviders.add(daoAuthenticationProvider());
        authenticationProviders.add(h5mobilecodeAuthenticationProvider());
        ProviderManager authenticationManager = new ProviderManager(authenticationProviders);
//        authenticationManager.setEraseCredentialsAfterAuthentication(false);
        return authenticationManager;
    }

//    @Bean
//    public AuthenticationManager authenticationManager() {
//        List authenticationProviders = new ArrayList();
//        authenticationProviders.add(mobilecodeAuthenticationProvider());
//        authenticationProviders.add(daoAuthenticationProvider());
//        ProviderManager authenticationManager = new ProviderManager(authenticationProviders);
////        authenticationManager.setEraseCredentialsAfterAuthentication(false);
//        return authenticationManager;
//
//    }

    @Bean
    public DaoAuthenticationProvider daoAuthenticationProvider() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
        daoAuthenticationProvider.setUserDetailsService(userDetailsService);
        return daoAuthenticationProvider;
    }

    @Bean
    public MobilecodeAuthenticationProvider mobilecodeAuthenticationProvider() {
        MobilecodeAuthenticationProvider mobilecodeAuthenticationProvider = new MobilecodeAuthenticationProvider();
        mobilecodeAuthenticationProvider.setUserDetailsService(userDetailsService);
        return mobilecodeAuthenticationProvider;
    }
    @Bean
    public H5MobilecodeAuthenticationProvider h5mobilecodeAuthenticationProvider() {
        H5MobilecodeAuthenticationProvider h5mobilecodeAuthenticationProvider = new H5MobilecodeAuthenticationProvider();
        h5mobilecodeAuthenticationProvider.setUserDetailsService(h5MyUserDetailsService);
        return h5mobilecodeAuthenticationProvider;
    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }
  /*  @Bean
    HttpSessionEventPublisher httpSessionEventPublisher() {
        return new HttpSessionEventPublisher();
    }*/


 /*   @Bean
    @ConditionalOnMissingBean(SessionInformationExpiredStrategy.class)
    public SessionInformationExpiredStrategy informationExpiredStrategy(){
        return new MySessionInformationExpiredStrategy();
    }*/




}
